﻿package elements 
{
	
	import events.InputFIeldEvent;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.FocusEvent;
	import flash.events.KeyboardEvent;
	import flash.events.MouseEvent;
	import flash.geom.ColorTransform;
	import flash.text.TextField;
	import flash.text.TextFieldType;
	import flash.text.TextFormat;
	import flash.ui.Keyboard;
	import gs.easing.Expo;
	import gs.TweenMax;
	import styles.InputFieldStyle;
	import util.Bounds;
	
	/**
	 * текстовое поле, в которое можно что-то вводить
	 * @author kasoi
	 */
	
	public class InputField extends Sprite 
	{
		/////////////////////////////////////////////////////////////////////////////
		// Properties
		/////////////////////////////////////////////////////////////////////////////
		
		public function get text() : String
		{
			return this._textField.text
		}
		
		public function set text(value: String) : void
		{
			this._textField.text = value;
		}
		
		public function get textField() : TextField
		{
			return this._textField;
		}
		
		public function get format() : TextFormat
		{
			return this._format;
		}
		
		public function set format(value: TextFormat) : void 
		{
			this._format = value;
			this._format.color = this._style.textNormalColor;
			this._textField.defaultTextFormat = this._format;
		}
		
		public function get background() : Sprite
		{
			return this._background;
		}
		
		public function get style() : InputFieldStyle 
		{
			return this._style;
		}
		
		public function get defaultText() : String 
		{ 
			return this._defaultText; 
		}
		
		public function set defaultText(value: String) : void 
		{
			this._defaultText = value;
		}
		
		public function get textWithoutDefault() : String 
		{ 
			var defaultText: String = this._defaultText;
			var currentText: String = this._textField.text;
			if (_defaultText == currentText) 
			{
				return '';
			}
			else return currentText;
		}
		
		/////////////////////////////////////////////////////////////////////////////
		// Privates
		/////////////////////////////////////////////////////////////////////////////
		
		private var _background: Sprite;
		
		private var isFocused: Boolean = false;
		
		private var _style: InputFieldStyle;
		
		private var _textField: TextField;
		
		private var _format: TextFormat;
		
		private var _size: Bounds;
		
		private var _defaultText: String;
		
		/////////////////////////////////////////////////////////////////////////////
		// Public methods
		/////////////////////////////////////////////////////////////////////////////
		
		public function InputField(size: Bounds, style: InputFieldStyle = null,
			defaultText: String = null) 
		{
			this._defaultText = defaultText;
			this._size = size;
			
			if (style == null) style = new InputFieldStyle();
			this._style = style;
			
			var format: TextFormat = new TextFormat(style.fontName, style.fontSize);
			
			this._textField = new TextField();
			this._textField.defaultTextFormat = format;
			this._textField.width = size.width;
			this._textField.height = style.fontSize + 8;
			this._textField.textColor = style.textNormalColor;
			this._textField.type = TextFieldType.INPUT;
			this._textField.text = this._defaultText;
			if(style.fontName != 'tahoma') this._textField.embedFonts = true;
			if (this._size.height > this._textField.textHeight * 2 + 6) 
			{
				this._textField.multiline = true;
				this._textField.wordWrap = true;
				this._textField.height = size.height - 2;
			}
			else this._textField.y = this._size.height / 2 - this.textField.height / 2 - 2;
			
			this._textField.y += 2;
			this._textField.x += 3;
			
			this._background = new Sprite();
			
			this._background.graphics.beginFill(style.backgroundNormalColor, style.backgroundAlpha);
			this._background.graphics.drawRoundRect(0, 0, size.width, size.height, 
				style.backgroundRoundness, style.backgroundRoundness);
			this._background.graphics.endFill();
			
			this.addChild(this._background);
			this.addChild(this._textField);
			
			this._textField.addEventListener(MouseEvent.MOUSE_OVER, this.textField_onMouseOver);
			this._textField.addEventListener(MouseEvent.MOUSE_OUT, this.textField_onMouseOut);
			this._textField.addEventListener(FocusEvent.FOCUS_IN, this.textField_onFocusIn);
			this._textField.addEventListener(FocusEvent.FOCUS_OUT, this.textField_onFocusOut);
			this._textField.addEventListener(Event.CHANGE, this.textField_onChange);
			this._textField.addEventListener(KeyboardEvent.KEY_UP, this.textField_onKeyUp);
			this._textField.addEventListener(KeyboardEvent.KEY_DOWN, this.textField_onKeyDown);
		}
		
		/////////////////////////////////////////////////////////////////////////////
		// Private methods
		/////////////////////////////////////////////////////////////////////////////
		
		private function tween_onComplete(color: Number) : void 
		{
			this._textField.transform.colorTransform = new ColorTransform();
			this._textField.textColor = color;
		}
		
		private function checkDefaultText(focusedIn: Boolean = false) : void 
		{
			var text: String = this._textField.text;
			if (text == this._defaultText && focusedIn) this._textField.text = '';
			if (text == '' && !focusedIn) this._textField.text = this._defaultText;
		}
		
		/////////////////////////////////////////////////////////////////////////////
		// Listeners
		/////////////////////////////////////////////////////////////////////////////
		
		private function textField_onMouseOver(e: MouseEvent) : void 
		{
			if (this.isFocused) return;
			var color: Number = this._style.textHoverColor;
			TweenMax.to(this._background, 0.2, {tint: this._style.backgroundHoverColor});
			TweenMax.to(this._textField, 0.1, {tint: color
				,onComplete: this.tween_onComplete, onCompleteParams: [color]});
		}
		
		private function textField_onMouseOut(e: MouseEvent) : void 
		{
			if (this.isFocused) return;
			var color: Number = this._style.textNormalColor;
			TweenMax.to(this._background, 0.2, {tint: this._style.backgroundNormalColor});
			TweenMax.to(this._textField, 0.1, {tint: color
				,onComplete: this.tween_onComplete, onCompleteParams: [color]});
		}
		
		private function textField_onFocusIn(e: FocusEvent) : void 
		{
			this.checkDefaultText(true);
			var color: Number = this._style.textActiveColor;
			TweenMax.to(this._background, 0.1, {tint: this._style.backgroundActiveColor});
			TweenMax.to(this._textField, 0.1, {tint: color
				,onComplete: this.tween_onComplete, onCompleteParams: [color]});
			this.isFocused = true;
		}
		
		private function textField_onFocusOut(e: FocusEvent) : void 
		{
			this.checkDefaultText(false);
			TweenMax.to(this._background, 1, {tint: this._style.backgroundNormalColor, ease: Expo.easeOut});
			var color: Number = this._style.textNormalColor;
			TweenMax.to(this._textField, 0.1, {tint: color
				,onComplete: this.tween_onComplete, onCompleteParams: [color]});
			this.isFocused = false;
		}
		
		private function textField_onChange(e: Event) : void 
		{
			this.dispatchEvent(new Event(Event.CHANGE));
		}
		
		private function textField_onKeyUp(e: KeyboardEvent) : void 
		{
			if (e.keyCode == Keyboard.ENTER)
			{
				this.dispatchEvent(new InputFIeldEvent(InputFIeldEvent.ENTER_RELEASE));
			}
		}
		
		private function textField_onKeyDown(e: KeyboardEvent) : void 
		{
			if (e.keyCode == Keyboard.ENTER)
			{
				this.dispatchEvent(new InputFIeldEvent(InputFIeldEvent.ENTER_PRESS));
			}
		}
	}
	
}